﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Xoohoo.Configuration;
using Xoohoo.Extensions;
using Xoohoo.Infrastructure.InversionOfControl;
using Xoohoo.Infrastructure;
using Xoohoo.Models;
using Xoohoo.Models.InputModels;
using Xoohoo.Models.ViewModels;
using Xoohoo.Services;

namespace Xoohoo.Modules.Admin.Controllers
{
    public class SystemController : Controller, IModuleSubMenu
    {
        private readonly ISiteService _siteService;
        private readonly IBulletinService _bulletinService;
        private readonly IPermissionService _perService;
        private readonly XoohooContext _context;
        private readonly IDependencyInjector _dependencyInjector;

        public SystemController(ISiteService siteService
            , IBulletinService bulletinService
            , IPermissionService perService
            , XoohooContext context
            , IDependencyInjector dependencyInjector
            )
 
        {
            this._siteService = siteService;
            this._bulletinService = bulletinService;
            this._perService = perService;
            this._context = context;
            this._dependencyInjector = dependencyInjector;
        }

        #region IModuleSubMenu Members

        public XoohooViewModelItem<ModuleSubMenuItemList> SubMenu()
        {
            var sm = new ModuleSubMenuItemList("系统管理") { 
                 new ModuleSubMenuItemSingle{ Title="系统管理", MenuLevel=1,Permission="系统管理"}
                ,new ModuleSubMenuItemSingle{ Title="系统配置", ContentRouteName="Admin.System.SiteConfig", MenuLevel=2,Permission="系统配置"}
                ,new ModuleSubMenuItemSingle{ Title="系统公告", ContentRouteName="Admin.System.Bulletin", MenuLevel=2,Permission="系统公告"}
                ,new ModuleSubMenuItemSingle{ Title="重启系统", ContentRouteName="Admin.System.Restart", MenuLevel=2,Permission="重启系统"}
                ,new ModuleSubMenuItemSingle{ Title="模块管理", MenuLevel=1,Permission="模块管理"}
                ,new ModuleSubMenuItemSingle{ Title="模块信息", ContentRouteName="Admin.System.Modules", MenuLevel=2,Permission="模块信息"}
                ,new ModuleSubMenuItemSingle{ Title="提取权限", ContentRouteName="Admin.System.ExtractModulePermissions", MenuLevel=2,Permission="提取权限"}
                ,new ModuleSubMenuItemSingle{ Title="清理权限", ContentRouteName="Admin.System.ClearModulePermissions", MenuLevel=2,Permission="清理权限"}
            };

            sm.RemoveAll(item => !_context.User.HasPermission(item.Permission));
            return new XoohooViewModelItem<ModuleSubMenuItemList>(sm);
        }

        #endregion

        public object Bulletin()
        {
            var bulletin = _bulletinService.GetItem();
            if (bulletin == null) return null;
            var bulletinInput = bulletin.ToModel<BulletinInput>();
            return new XoohooViewModelItem<BulletinInput>(bulletinInput);
        }
        [HttpPost]
        public object Bulletin(BulletinInput bulletinInput)
        {
            PromptViewModel prompt = new PromptViewModel("系统公告");
            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);

            if (bulletinInput == null)
            {
                prompt.AddMessage("尚未获取系统公告！");
                return View("Prompt", xvm);
            }

            if (TryValidateModel(bulletinInput))
            { 
                _bulletinService.Save(bulletinInput);
                prompt.AddMessage("系统公告修改成功！");
            }
            else
            {
                return new XoohooViewModelItem<BulletinInput>(bulletinInput);
                //prompt.AddModelErrors(ModelState);
            }

            return View("Prompt",xvm);
        }

        public object SiteConfig()
        {
            Site site = _siteService.GetItem();
            if (site == null) return null;
            SiteInput siteInput = site.ToModel<SiteInput>();
            return new XoohooViewModelItem<SiteInput>(siteInput);
        }
        [HttpPost]
        public object SiteConfig(SiteInput siteInput)
        {
            PromptViewModel prompt = new PromptViewModel("系统配置");
            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);

            if (siteInput == null)
            {
                prompt.AddMessage("尚未获取系统配置！");
                return View("Prompt", xvm);
            }

            if (TryValidateModel(siteInput))
            {
                if (_siteService.Save(siteInput))
                {
                    prompt.AddMessage("系统配置信息修改成功！");
                    prompt.AddMessage("重新启动系统后将会加载最新的配置。");
                    prompt.AddMessage("如果您修改了【皮肤主目录】、【脚本主目录】、【样式主目录】等，需要手工调整相应目录并重启。");
                    prompt.AddMessage("如果您修改了【后台目录】，重启系统后需要输入正确的新的后台地址。");
                }
                else
                {
                    prompt.AddMessage("系统配置信息修改失败，原因未知！");
                }
            }
            else
            {
                return new XoohooViewModelItem<SiteInput>(siteInput);
                //prompt.AddModelErrors(ModelState);
            }

            return View("Prompt",xvm);

        }

        public object Modules()
        {
            XoohooConfigurationSection moduleConfig = _dependencyInjector.GetService<XoohooConfigurationSection>();
            return new XoohooViewModelItem<XoohooConfigurationSection>(moduleConfig);
        }

        public object ExtractModulePermissions()
        {
            PromptViewModel prompt = new PromptViewModel("提取权限");

            IEnumerable<PermissionInput> permissions;
            IEnumerable<IModuleMetaData> modules = _dependencyInjector.GetService<IModuleRegistry>().GetModules<IModuleMetaData>();
            foreach (var module in modules)
            {
                //ModelResult modelResult = perService.Save(module.GetModulePermissions().OrderBy(p => p.PermissionLevel));
                //ModelResult modelResult = perService.Save(module.GetModulePermissions().OrderBy(p => p.DisplayOrder));

                permissions = module.GetModulePermissions();
                if (permissions == null) continue;

                ModelResult modelResult = _perService.Save(module.GetModulePermissions());
                if (!modelResult.IsValid)
                {
                    prompt.AddMessage("提取权限失败！");
                    prompt.AddModelErrors(modelResult.Errors);
                    return prompt;
                }
            }
            prompt.AddMessage("提取权限成功！");

            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
            return View("Prompt",xvm);
        }

        public object ClearModulePermissions()
        {
            //如下实现方式是先从模块中获取全部权限信息，然后从数据库中获取全部权限信息
            //求其差集再删除
            //最佳实现方案当然是将ID传到数据库
            //以delete * from Permission Where PermissionID not in(...)的方式或者 or 的方式

            PromptViewModel prompt = new PromptViewModel("清理权限");

            IEnumerable<IModuleMetaData> modules = _dependencyInjector.GetService<IModuleRegistry>().GetModules<IModuleMetaData>();
            List<Guid> modulePermissionIDs = new List<Guid>();
            foreach (var module in modules)
            {
                IEnumerable<PermissionInput> modulePermissions = module.GetModulePermissions();
                if (modulePermissions != null)
                    modulePermissionIDs.AddRange(modulePermissions
                        .Where(m=>m.PermissionID.HasValue)
                        .Select(m=>m.PermissionID.Value));
            }

            IEnumerable<Guid> perToClear = _perService.GetList()
                .OrderByDescending(m=>m.PermissionLevel)
                .Select(m => m.PermissionID)
                .Except(modulePermissionIDs);                                           

            _perService.Remove(perToClear);

            prompt.AddMessage("清理权限成功！");

            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
            return View("Prompt",xvm);
        }

        public object Restart()
        {
            bool result = _siteService.Restart();

            PromptViewModel prompt = new PromptViewModel("重启系统");
            prompt.AddMessage(result ? "重启系统成功！" 
                    : "重启系统失败！请确认对系统根目录下的Web.Config有写入的操作权限。");
            prompt.ReturnText = "刷新页面";
            prompt.ReturnUrl = "javascript:top.location.reload();";

            var xvm = new XoohooViewModelItem<PromptViewModel>(prompt);
            return View("Prompt",xvm);
        }

    }
}
